home *** CD-ROM | disk | FTP | other *** search
- /*
- File: TextField.cpp
-
- Contains: TextEdit class to contain TextEdit from Toolbox
-
- Written by: Andrew Taylor
-
- Theory of Operation:
- Quick and dirty wrapper for TextEdit
-
- Copyright: © 1995 by Appropriate Solutions, Inc., all rights reserved.
-
- Change History (most recent first):
-
-
- <0> started
- */
-
- #ifndef _TEXTFIELD_
- #include "TextField.h"
- #endif
-
- #ifndef __DIALOGS__
- #include <Dialogs.h>
- #endif
-
- const char kRightArrow = 0x1D;
- const char kLeftArrow = 0x1C;
- const char kUpArrow = 0x1E;
- const char kDownArrow = 0x1F;
-
-
- //========================================================================================
- // TextField
- //========================================================================================
-
- TextField::TextField()
- {
- fTheTE = nil;
- fMaxChars = 0;
- fIdentifier = 0;
- fAnchorPoint = 0;
- }
-
- //----------------------------------------------------------------------------------------
-
- TextField::~TextField()
- {
- }
-
- //----------------------------------------------------------------------------------------
-
- void TextField::InitTextField(ODTypeToken id, short maxChars, Rect *destRect)
- // id is the identifier for this field
- // destRect is converted to dest, view and passed to TENew.
- // maxChars is the maximum characters allowed in the field
- {
- Rect dest, view;
-
- dest = *destRect;
- view = *destRect;
-
- ::InsetRect(&dest, 2, 2);
- ::InsetRect(&view, 2, 2);
- if (nil == fTheTE)
- fTheTE = ::TENew(&dest, &view);
- else
- {
- (*fTheTE)->destRect = dest;
- (*fTheTE)->viewRect = view;
- ::InvalRect(&view);
- }
- fIdentifier = id;
- fMaxChars = maxChars;
- }
-
- //----------------------------------------------------------------------------------------
-
- void TextField::ReleaseTextField()
- // dispose of TextEdit record
- {
- if (fTheTE)
- ::TEDispose(fTheTE);
- fTheTE = nil;
- }
-
-
- //----------------------------------------------------------------------------------------
-
- Boolean TextField::KeyStroke(char inKey, short modifiers)
- // enter keystroke into TE record
- // returns true if keystroke accepted
- {
- Boolean result = false;
- short length;
- short selStart = (*fTheTE)->selStart;
- short selEnd = (*fTheTE)->selEnd;
-
- if ( selEnd == selStart )
- fAnchorPoint = selStart;
-
- if (modifiers & shiftKey)
- {
- switch (inKey)
- {
- case kRightArrow:
- {
- if (fAnchorPoint < selStart)
- selStart += 1;
- else
- selEnd += ( selEnd < 32000) ? 1 : 0;
- ::TESetSelect(selStart, selEnd, fTheTE);
- result = true;
- break;
- }
-
- case kLeftArrow:
- {
- if (fAnchorPoint < selEnd)
- selEnd -= 1;
- else
- selStart -= ( selStart > 0) ? 1 : 0;
- ::TESetSelect(selStart, selEnd, fTheTE);
- result = true;
- break;
- }
- }
- }
- if (modifiers & cmdKey)
- return(result);
- if (!result)
- {
- // allow keystrokes if max chars and there is a selection range.
- length = (*fTheTE)->teLength - ((*fTheTE)->selEnd - (*fTheTE)->selStart);
- if ( (length < fMaxChars) || ((inKey < ' ') || (inKey > 'z')) )
- {
- // Strange TextEdit bug remedy... (Thanks to Patrick Doane)
- (*fTheTE)->clikStuff = -1;
- ::TEKey(inKey, fTheTE);
- result = true;
- }
- }
- return(result);
- }
-
- //----------------------------------------------------------------------------------------
-
- Boolean TextField::ContainsPoint(Point where)
- // Determines if point is contained within the view rect.
- {
- return( PtInRect(where, &(**fTheTE).viewRect) );
- }
-
- //----------------------------------------------------------------------------------------
-
- void TextField::MouseClick(Point where, EventRecord *event)
- // pass mouse click to TextEdit
- {
- ::TEClick(where, (event->modifiers & shiftKey) == shiftKey, fTheTE);
- fAnchorPoint = (*fTheTE)->selStart;
- }
-
- //----------------------------------------------------------------------------------------
-
- void TextField::Draw(RgnHandle invalRgn)
- // draw frame box
- // update TextEdit display
- {
- Rect rct = (**fTheTE).viewRect;
- ::InsetRect(&rct, -2, -2);
- ::FrameRect(&rct);
- ::TEUpdate(&(**invalRgn).rgnBBox, fTheTE);
- }
-
- //----------------------------------------------------------------------------------------
-
- Handle TextField::GetTextHandle(long *usedLength)
- // retrieve TextEdit record handle
- {
- *usedLength = (**fTheTE).teLength;
- return (**fTheTE).hText;
- }
-
- //----------------------------------------------------------------------------------------
-
- Handle TextField::GetSelectedPtr(Ptr *data, long *length)
- // set ptr to selected text. Set length of selected text.
- // caller is expected to lock and unlock handle if use of ptr
- // will cause memory move.
- {
- *length = ((**fTheTE).selEnd - (**fTheTE).selStart);
- *data = ( &( (*(**fTheTE).hText)[(**fTheTE).selStart] ) );
- return((**fTheTE).hText);
- }
-
- //----------------------------------------------------------------------------------------
-
- void TextField::SetSelection(long start, long end)
- // set the selection range
- {
- ::TESetSelect(start, end, fTheTE);
- fAnchorPoint = start;
- }
-
- //----------------------------------------------------------------------------------------
-
- void TextField::GetText(Str255 str)
- // retrieve text from TextEdit record
- {
- ::GetDialogItemText((**fTheTE).hText, str);
- }
-
- //----------------------------------------------------------------------------------------
-
- void TextField::SetText(Str255 str)
- // load TextEdit record with text
- {
- ::TESetText( (Ptr)&str[1], (long)str[0], fTheTE);
- }
-
- //----------------------------------------------------------------------------------------
-
- Boolean TextField::Validate()
- // check for valid field contents. Display failure reason to user
- // return true for good contents, false for bad.
- {
- return(true);
- }
-
- //----------------------------------------------------------------------------------------
-
- void TextField::Activate()
- // make this the active TE record
- {
- ::TEActivate(fTheTE);
- }
-
- //----------------------------------------------------------------------------------------
-
- void TextField::Deactivate()
- // deactivate TE record
- {
- ::TEDeactivate(fTheTE);
- }
-
- //----------------------------------------------------------------------------------------
-
- void TextField::Idle()
- // do some idle time.
- {
- ::TEIdle(fTheTE);
- }
-
-
- //----------------------------------------------------------------------------------------
-
- void TextField::Cut()
- {
- ::TECut(fTheTE);
- }
-
- //----------------------------------------------------------------------------------------
-
- void TextField::Copy()
- {
- ::TECopy(fTheTE);
- }
-
- //----------------------------------------------------------------------------------------
-
- void TextField::Paste()
- {
- ::TEPaste(fTheTE);
- }
-
- //----------------------------------------------------------------------------------------
-
- void TextField::Clear()
- {
- ::TEDelete(fTheTE);
- }
-
- //----------------------------------------------------------------------------------------
-
- Boolean TextField::HaveSelection()
- {
- return( ((**fTheTE).selStart != (**fTheTE).selEnd) );
- }
-
-
- //========================================================================================
- // LabeledTextField
- //========================================================================================
-
- LabeledTextField::LabeledTextField()
- {
- fLabel[0] = 0;
- }
-
- //----------------------------------------------------------------------------------------
-
- LabeledTextField::~LabeledTextField()
- {
- }
-
- //----------------------------------------------------------------------------------------
-
- void LabeledTextField::InitTextField(ODTypeToken id, short maxChars, short lblWidth, Rect *destRect, Str255 str)
- // id is the identifier for this field
- // destRect is converted to dest, view and passed to TENew.
- // maxChars is the maximum characters allowed in the field
- {
- fRect = *destRect;
- destRect->left += lblWidth;
- if (destRect->left >= destRect->right) // nuff room for edit and label?
- destRect->left = destRect->right - lblWidth/2; //let the fields fight it out
- ::BlockMove(&str[0], &fLabel[0], str[0]+1);
-
- TextField::InitTextField(id, maxChars, destRect);
- }
-
- //----------------------------------------------------------------------------------------
-
- void LabeledTextField::Draw(RgnHandle invalRgn)
- {
- // place pen at left of field, up a little from the bottom
- ::MoveTo(fRect.left, fRect.bottom - 6 ); // rgac 2);
- ::DrawString(fLabel);
- TextField::Draw(invalRgn);
- }
-
-
-
- //========================================================================================
- // TextFieldLink
- //========================================================================================
-
-
- TextFieldLink::TextFieldLink( )
- {
- fTextField = kODNULL;
- fPrev = this;
- fNext = this;
- }
-
- //----------------------------------------------------------------------------------------
-
- TextFieldLink::TextFieldLink( TextField *field, TextFieldLink *list )
- {
- fTextField = field;
- fPrev = list;
- fNext = list->fNext;
- list->fNext = this;
- fNext->fPrev = this;
- }
-
- //----------------------------------------------------------------------------------------
-
- TextFieldLink::~TextFieldLink( )
- {
- if ( fPrev )
- fPrev->fNext = fNext;
- if ( fNext )
- fNext->fPrev = fPrev;
- }
-
-
- //========================================================================================
- // TextFieldList
- //========================================================================================
-
- TextFieldList::TextFieldList()
- {
- fTextField = kODNULL;
- fPrev = kODNULL;
- fNext = this;
- }
-
- //----------------------------------------------------------------------------------------
-
- TextFieldList::~TextFieldList( )
- {
- // Delete all links:
- while ( fNext != this )
- delete fNext;
- }
-
- //----------------------------------------------------------------------------------------
-
- void TextFieldList::Add( TextField *field )
- {
- new TextFieldLink(field,this);
- // The new link has already hooked itself into my chain so I don't need to
- // remember it elsewhere.
- }
-
- //----------------------------------------------------------------------------------------
-
- void TextFieldList::Remove( TextField *field )
- {
- TextFieldLink *link;
- for ( link = this->First(); link->GetTextField(); link = link->Next() ) {
- if ( link->GetTextField() == field ) {
- delete link;
- return;
- }
- }
-
- DebugStr("\pCouldn't find field");
- }
-
- //----------------------------------------------------------------------------------------
-
- void TextFieldList::Add(ODTypeToken id, short maxChars, Rect *destRect)
- {
- TextField *aField = new TextField();
- aField->InitTextField(id, maxChars, destRect);
- this->Add(aField);
-
- }
-
- //----------------------------------------------------------------------------------------
-
- void TextFieldList::Add(ODTypeToken id, short maxChars, short lblWidth, Rect *destRect, Str255 label)
- {
- LabeledTextField *aField = new LabeledTextField();
- aField->InitTextField(id, maxChars, lblWidth, destRect, label);
- this->Add(aField);
-
- }
-